<?
/*
 *  GGB - Gelin's Guest Book.
 *  Copyright (C) 2007  Denis Nelubin aka Gelin
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  http://gelin.ru
 *  mailto:den@gelin.ru
 *
 *  Description:    Logger for messages which should be displayed to user.
 *
 *  History:
 *  2007-07-07  Gelin   Initially created.
 *  2007-07-22  Gelin   Logger is modified.
 *
 */

/**
 *  Global storage for error messages. Use only require_once() or include_once()
 *  to use this file to avoid messages missing.
 */
$logMessages = array();

/**
 *  Logger for messages. This messages can be displayed to user. These are,
 *  for example, error messages.
 *  Each instance of a Logger has a name. Names are hierarchially ordered.
 *  Root logger has a "" (empty string) name. Each logger aggregates messages
 *  For itself and for all inner loggers.
 */
class Logger {

    /** this logger name */
    var $name;

    /**
     *  Constructor.
     *  @param  $name   this logger name (default = '')
     */
    function Logger($name = '') {
        $this->name = $name;
        $this->clear();
    }

    /** Logs fatal message. Adds message to this logger. */
    function fatal($message) {
        global $logMessages;
        $logMessages[$this->name]['fatal'][] = $message;
    }

    /** Logs error message. Adds message to this logger. */
    function error($message) {
        global $logMessages;
        $logMessages[$this->name]['error'][] = $message;
    }

    /** Logs warn message. Adds message to this logger. */
    function warn($message) {
        global $logMessages;
        $logMessages[$this->name]['warn'][] = $message;
    }

    /** Logs info message. Adds message to this logger. */
    function info($message) {
        global $logMessages;
        $logMessages[$this->name]['info'][] = $message;
    }

    /** Logs debug message. Adds message to this logger. */
    function debug($message) {
        global $logMessages;
        $logMessages[$this->name]['debug'][] = $message;
    }

    /** Returns list of fatal messages of this and sub-loggers. */
    function getFatals() {
        $messages = $this->getMessages();
        return $messages['fatal'];
    }

    /** Returns list of error messages of this and sub-loggers. */
    function getErrors() {
        $messages = $this->getMessages();
        return $messages['error'];
    }

    /** Returns list of warn messages of this and sub-loggers. */
    function getWarns() {
        $messages = $this->getMessages();
        return $messages['warn'];
    }

    /** Returns list of info messages of this and sub-loggers. */
    function getInfos() {
        $messages = $this->getMessages();
        return $messages['info'];
    }

    /** Returns list of debug messages of this and sub-loggers. */
    function getDebugs() {
        $messages = $this->getMessages();
        return $messages['debug'];
    }

    /** Returns TRUE if list of fatal messages of this and sub-loggers is empty. */
    function isFatalsEmpty() {
        return count($this->getFatals()) == 0;
    }

    /** Returns TRUE if list of error messages of this and sub-loggers is empty. */
    function isErrorsEmpty() {
        return count($this->getErrors()) == 0;
    }

    /** Returns TRUE if list of warn messages of this and sub-loggers is empty. */
    function isWarnsEmpty() {
        return count($this->getWarns()) == 0;
    }

    /** Returns TRUE if list of info messages of this and sub-loggers is empty. */
    function isInfosEmpty() {
        return count($this->getInfos()) == 0;
    }

    /** Returns TRUE if list of debug messages of this and sub-loggers is empty. */
    function isDebugsEmpty() {
        return count($this->getDebugs()) == 0;
    }

    /** Saves list of all (of all loggers) messages to session. */
    function save() {
        global $logMessages;
        $_SESSION['logMessages'] = $logMessages;
    }

    /** Restores list of all (of all loggers) messages from session. */
    function restore() {
        global $logMessages;
        $logMessages = $_SESSION['logMessages'];
    }

    /** Clears list of messages of this logger. */
    function clear() {
        global $logMessages;
        $messages = $logMessages[$this->name];
        $messages['fatal'] = array();
        $messages['error'] = array();
        $messages['warn'] = array();
        $messages['info'] = array();
        $messages['debug'] = array();
    }

    /** Gets array of messages of this and sub-loggers. */
    function getMessages() {
        global $logMessages;
        $result = array();
        if (count($logMessages) > 0) {
            foreach ($logMessages as $name => $logger) {
                if ($this->startsWith($name, $this->name)) {    //this or sub-logger
                    foreach ($logger as $level => $messages) {
                        foreach ($messages as $message) {
                            $result[$level][] = $message;
                        }
                    }
                }
            }
        }
        return $result;
    }

    /** Returns TRUE if string1 is started from value of string2 */
    function startsWith($string1, $string2) {
        if ($string2 == '') {
            return TRUE;
        }
        return (strpos($string1, $string2) === 0);  //exactly zero, not FALSE
    }

}

?>